---------------------------------------------------------------
-- @Copyright：           zour
-- @Description：         累计收益

-- @modify time           2021-12-3
---------------------------------------------------------------
-- 文件
local gg         = require("modules.business_welfare.welfare_gg")
local config     = require("modules.business_welfare.welfare_lua_config")
local uu         = require("modules.commhm.utils")
local ns_account = require("modules.business_welfare.welfare_bridge")
local log        = require("modules.commhm.log")
local code_conf  = require("modules.business_welfare.welfare_code")
local op_log     = require("modules.business_welfare.welfare_op_log")
local g_enum     = require("modules.business_welfare.welfare_enum")

-- 变量 开头定义优先级 系统库 > ngx > 自定义
local pairs      = pairs
local math       = math
local ngx = ngx
local tonumber = tonumber
local table  = table
local type = type
local error_code = code_conf.error_code

local FOO = {}

--=================================== 累计收益需求相关 =====================================
local function private_hash_get_multi_key ( t )
    local kv_list = {}
    for _, v in pairs(t) do
        if v and v>0 then 
            table.insert( kv_list, { key=ngx.ctx.m_params.uin, hash=v } )
        end
    end

    local ret_key_list = {}
	local ret_list = gg.private_hash_mread_table_ssdb( ngx.ctx.m_params.uin, kv_list)
	if #ret_list == #t then
		for i=1, #ret_list do
            ret_list[i].__key = nil
            ret_key_list[kv_list[i].hash] = ret_list[i]
		end
	end

    return ret_key_list
end

--初始化时只是记录计算起点，无须计算收益
local function init_accumulate_data(t_config, now_time)
    local user_tag_data = {}

    --初次点击时间
    user_tag_data.now_time = now_time
    --初始累计速率
    --user_tag_data.base_rate = t_config.accumulate_rate 
    --初始累计上限
    --user_tag_data.base_max_start = t_config.accumulate_max_start
    --改成了单个物品对应单个速率
    user_tag_data.rewards_items = t_config.accumulate_rewards 
    --
    user_tag_data.base_num = {}
    user_tag_data.base_num[g_enum.Mode_accumulate.accumulate_rewards.normal] = {}
    user_tag_data.base_num[g_enum.Mode_accumulate.accumulate_rewards.advert] = {}

    --累计时间
    user_tag_data.delta_time = 0
    --增益表
    user_tag_data.delta_list = {}
    --奖励表
    user_tag_data.rewards_table = {}

    return user_tag_data
end

--客户端请求累计收益玩法红点
FOO.check_accumulate_point = function ()
    if not tonumber(ngx.ctx.m_params.uin) then 
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (check_accumulate_point) ERROR_PARAM! uin= "
            ..( tonumber(ngx.ctx.m_params.uin) or "nil") )
        return error_code.ERROR_PARAM
	end

    local uin = tonumber(ngx.ctx.m_params.uin)
    local channel = tonumber(ngx.ctx.m_params.apiid) 
    local t_config = config.get_cfg("Mode_accumulate")
    if not t_config 
    or not t_config.open_window_rate then 
        return error_code.ERROR_CHECK_CONFIG
    end

    local v_list = private_hash_get_multi_key(g_enum.Mode_accumulate.accumulate_ssdb_keys)

    local red_point_tags = {}
    for _, tag in pairs(g_enum.Mode_accumulate.accumulate_tags) do
        local user_tag_data = v_list[ g_enum.Mode_accumulate.accumulate_ssdb_keys[tag] ] 
        if user_tag_data and user_tag_data.now_time then 
            local delta_time = uu.now() - user_tag_data.now_time   
            if delta_time >= (t_config.open_window_rate*g_enum.Mode_accumulate.hour_sec) then 
                red_point_tags[tag] = 1
            end
        end
    end

    --日志
    if #red_point_tags>0 then 
        log.day_list("check_accumulate_point", "[INFO] check_accumulate_point uin="..uin.." ret="..table.tostring(red_point_tags))
    end
    
    return error_code.COMMON_SUCCESS, red_point_tags
end

--计算速率
local function calc_accumulate_data(user_tag_data, t_config, now_time, delta_time)
    --默认增益数据
    --user_tag_data.base_rate = t_config.accumulate_rate
    --user_tag_data.base_max_start = t_config.accumulate_max_start
    --改成了单个物品对应单个速率
    user_tag_data.rewards_items = t_config.accumulate_rewards 
    user_tag_data.base_num = {}
    user_tag_data.base_num[g_enum.Mode_accumulate.accumulate_rewards.normal] = {}
    user_tag_data.base_num[g_enum.Mode_accumulate.accumulate_rewards.advert] = {}
    
    user_tag_data.now_time = now_time
    user_tag_data.delta_time = delta_time   --生效时间
    for reward_type, items in pairs(user_tag_data.rewards_items) do
        for item_id, item_infos in pairs(items) do
            --[[
            log.debug("====================================")
            log.debug("delta_time= "..delta_time)
            log.debug("g_enum.Mode_accumulate.hour_sec= "..g_enum.Mode_accumulate.hour_sec)
            log.debug("item_infos.rate= "..item_infos.rate)
            log.debug("(delta_time/ g_enum.Mode_accumulate.hour_sec) * item_infos.rate= "..(delta_time/ g_enum.Mode_accumulate.hour_sec) * item_infos.rate)
            log.debug("math.floor( (delta_time/ g_enum.Mode_accumulate.hour_sec) * item_infos.rate)= "..math.floor( (delta_time/ g_enum.Mode_accumulate.hour_sec) * item_infos.rate))
            --]]
            
            user_tag_data.base_num[reward_type][item_id] = math.floor( (delta_time/ g_enum.Mode_accumulate.hour_sec) * item_infos.rate)
            if user_tag_data.base_num[reward_type][item_id] > item_infos.limit then 
                user_tag_data.base_num[reward_type][item_id] = item_infos.limit
            end
        end
    end

    --到期时间戳
    user_tag_data.left_time_ts = now_time + (t_config.back_reward_time * g_enum.Mode_accumulate.hour_sec)

    --增益值源数据表为空时直接return了，无须增加增益
    if user_tag_data.delta_list==nil or #user_tag_data.delta_list==0 then 
        return 
    end

    --先将上次finish状态的清除一下[放在这里清是因为可以每次算完还可以查源数据]
    local tmp_t = {}
    for _, v in pairs(user_tag_data.delta_list) do
        if v.delta_status~=g_enum.Mode_accumulate.reward_status.finish then 
            table.insert(tmp_t, v)
        end
    end
    user_tag_data.delta_list = tmp_t

    --修改增益源数据
    for _, v in pairs(user_tag_data.delta_list) do
        v.delta_time = now_time - v.start_ts
        v.total_delta_time = v.total_delta_time + delta_time
        if v.delta_time > 0 then 
            --开始时间用当前时间
            v.last_ts = v.start_ts
            v.start_ts = now_time
            --一些状态修改
            v.delta_status = g_enum.Mode_accumulate.reward_status.ready
            v.leave_time = v.vaild_time - v.total_delta_time
            --超过有效时长就是完成状态，下次清除
            if v.total_delta_time >= v.vaild_time then 
                v.total_delta_time = v.vaild_time
                v.delta_status = g_enum.Mode_accumulate.reward_status.finish
                v.leave_time = 0    
            end

            --计算此次收益
            v.delta_num = math.floor( (v.delta_time/g_enum.Mode_accumulate.hour_sec) * v.delta_rate )
            if v.delta_num > v.delta_limit then 
                v.delta_num = v.delta_limit
            end
        end
    end
end

--计算物品获得
local function calc_accumulate_rewards(user_tag_data, t_config)
    --遍历奖励类型里面的物品ID，每个道具的数量算法为 默认+遍历增益部分
    user_tag_data.rewards_table = {}
    user_tag_data.back_reward = nil
    for _, reward_type in pairs(g_enum.Mode_accumulate.accumulate_rewards) do
        user_tag_data.rewards_table[reward_type] = {}
        user_tag_data.rewards_table[reward_type].reward_status = g_enum.Mode_accumulate.reward_status.ready
        for item_id, item_infos in pairs(t_config.accumulate_rewards[reward_type] ) do
            local item_delta_detail = {}
            item_delta_detail.base_num = user_tag_data.base_num[reward_type][item_id]
            item_delta_detail.delta_num = 0
            --再遍历增益部分
            for _, task_table in pairs(user_tag_data.delta_list) do
                for _, v in pairs(task_table.items) do
                    if v==item_id then 
                        item_delta_detail.delta_num = item_delta_detail.delta_num + task_table.delta_num
                    end 
                end
            end
            item_delta_detail.total_num = item_delta_detail.base_num + item_delta_detail.delta_num

            user_tag_data.rewards_table[reward_type][item_id] = item_delta_detail
        end
    end
end

--计算累计收益
local function calc_accumulate(user_tag_data, t_config, tag, now_time)
    --若点击时间小于开启时间，则用开启时间来计算
    if user_tag_data.now_time < t_config.open_window_notify[tag] then 
        user_tag_data.now_time = t_config.open_window_notify[tag]
    end
    local delta_time = now_time - user_tag_data.now_time
    if delta_time < (t_config.open_window_rate*g_enum.Mode_accumulate.hour_sec) then
        return false
    end

    --算累积数值
    calc_accumulate_data(user_tag_data, t_config, now_time, delta_time)
    --根据数值算奖励
    calc_accumulate_rewards(user_tag_data, t_config)

    return true
end

--发客户端数据
local function send_client_accumulate_data(user_tag_data, now_time)
    local ret_t = {}
    --[[
    --先预留下这个数据结构
    if user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal].reward_status==g_enum.Mode_accumulate.reward_status.ready then 
        --弹窗
        ret_t.open_window = {}
        ret_t.open_window.title = "累计收益"
        ret_t.open_window.accumulate_time = user_tag_data.delta_time
        ret_t.open_window.accumulate_time_hour =  user_tag_data.delta_time  / g_enum.Mode_accumulate.hour_sec 
        ret_t.open_window.normal_reward = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal]
        ret_t.open_window.advert_reward = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert]
    end

    --这里只赋值，有就有没有就没有。累积收益在领普通物品奖励时赋值，在领广告奖励时清除 
    ret_t.back_reward = user_tag_data.back_reward
    --此时就算不能弹窗，若有找回奖励也要重新计算找回奖励时间
    if ret_t.back_reward then 
        ret_t.back_reward.remain_time = ( (user_tag_data.back_reward.end_ts - now_time) / g_enum.Mode_accumulate.hour_sec )  
        if user_tag_data.back_reward.remain_time<=0 then 
            ret_t.back_reward = nil
        end
    end
    --]]
   
    --将数据结构转成客户端想要的样子
    ret_t.left_time_ts = user_tag_data.left_time_ts
    ret_t.normal_reward = {}
    local normal_reward_t = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal]
    if normal_reward_t and (normal_reward_t.reward_status==g_enum.Mode_accumulate.reward_status.ready) then 
        ret_t.normal_reward = normal_reward_t
        ret_t.normal_reward.reward_status = nil
    end
 
    ret_t.advert_reward = {}
    local advert_reward_t = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert]
    if advert_reward_t and (advert_reward_t.reward_status==g_enum.Mode_accumulate.reward_status.ready) then 
        ret_t.advert_reward = advert_reward_t
        ret_t.advert_reward.reward_status = nil
    end

    --找回
    if user_tag_data.back_reward and user_tag_data.back_reward.advert_reward then 
        ret_t.advert_reward = user_tag_data.back_reward.advert_reward
        ret_t.advert_reward.reward_status = nil
    end 

    return ret_t
end

--客户端请求累计收益玩法的弹窗和找回按钮
FOO.check_accumulate_tags = function ()
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (check_accumulate_tags) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil") .." tag="..(tonumber(ngx.ctx.m_params.tag) or "nil") )
        return error_code.ERROR_PARAM
	end
    
    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 
    
    --配置检查
    local t_config = config.get_cfg("Mode_accumulate")
    if not t_config  
    or not t_config.starttime 
    or not t_config.endtime 
    or not t_config.open_window_rate
    or not t_config.open_window_notify 
    or not t_config.open_window_notify[tag]
    or not t_config.accumulate_rewards then 
        return error_code.ERROR_CHECK_CONFIG
    end

    --检测配置时间
    local now_time = uu.now()
    if now_time<t_config.starttime or now_time>t_config.endtime then 
        return error_code.NOT_OPEN_ACCUMULATE
    end
    
    --若未开启弹窗[或时间还未到]，直接返回未开启弹窗的提示码
    if not t_config.open_window_notify[tag] 
        or (t_config.open_window_notify[tag]==0)
        or (now_time < t_config.open_window_notify[tag]) then   
        return error_code.NOT_OPEN_WINDOW_NOTIFY
    end
    
    --页面没有点击时间就初始化，否则就计算累计收益
    local ret, user_tag_data = gg.private_hash_get_table_ssdb(uin, uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag])
    local last_time_ts = user_tag_data.now_time
    local is_open_flag = 0
    local delta_time_ts = 0
    --user_tag_data.now_time = uu.now() - 3600
    if not user_tag_data.now_time then
        user_tag_data = init_accumulate_data(t_config, now_time)
        last_time_ts = now_time
        delta_time_ts = 0
    else
        delta_time_ts = now_time - user_tag_data.now_time
        local iret = calc_accumulate(user_tag_data, t_config, tag, now_time)
        if iret then 
            is_open_flag = 1
        end
    end
    
    --写入ssdb
    local ret = gg.private_hash_set_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, 
        g_enum.Mode_accumulate.accumulate_ssdb_keys[tag], user_tag_data)
    if ret~=true then 
        return error_code.ERROR_OP
    end

    --转成客户端数据并发送
    local ret_rewards = send_client_accumulate_data(user_tag_data, now_time)

    log.day_list("check_accumulate_tags", "[INFO] check_accumulate_tags uin="..uin.." is_open_flag="..is_open_flag
        .." last_time_ts="..last_time_ts.." uu.now="..now_time.." delta_time_ts="..delta_time_ts
        .." ret="..table.tostring(ret_rewards))

    return error_code.COMMON_SUCCESS, ret_rewards
end

--客户端领取普通收益奖励[此时一定是弹窗领取]
local function get_accumulate_reward_normal(t_config)
    if not tonumber(ngx.ctx.m_params.uin) 
	or not tonumber(ngx.ctx.m_params.apiid) 
    or not tonumber(ngx.ctx.m_params.tag) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert , "[ERROR] (get_accumulate_reward_normal) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil") .." channel=".. (tonumber(ngx.ctx.m_params.apiid) or "nil")
            .." tag= "..(tonumber(ngx.ctx.m_params.tag) or "nil"))

        return error_code.ERROR_PARAM
	end
    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 

    local ret, user_tag_data = gg.private_hash_get_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag])
    if ret~=error_code.COMMON_SUCCESS then 
        return error_code.ERROR_NO_DATA
    end

    --弱网环境已领奖校验
    if not user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal]
    or user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal].reward_status ~= g_enum.Mode_accumulate.reward_status.ready then 
        return error_code.ALREADY_GET_REWARDS
    end

    --弹窗初始时间修改
    local now_time = uu.now()
    user_tag_data.now_time = now_time
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal] = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal] or {}
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal].reward_status = g_enum.Mode_accumulate.reward_status.finish

    --此时写入找回奖励
    user_tag_data.back_reward = {}
    user_tag_data.back_reward.config_time = t_config.back_reward_time
    user_tag_data.back_reward.start_ts = now_time
    user_tag_data.back_reward.end_ts = user_tag_data.back_reward.start_ts + (user_tag_data.back_reward.config_time * g_enum.Mode_accumulate.hour_sec)
    user_tag_data.back_reward.advert_reward = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert]

    --写入ssdb
    local ret = gg.private_hash_set_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, 
        g_enum.Mode_accumulate.accumulate_ssdb_keys[tag], user_tag_data)
    if ret~=true then 
        return error_code.ERROR_OP
    end

    --发普通物品奖
    local rewards = {}
    for item_id, v in pairs(user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal]) do
        if type(v)=='table' then 
            table.insert(rewards, {id=item_id, num=v.total_num})
        end
    end
    local ret_account = ns_account.private_account.items_add(rewards, "accumulate_normal_rewards")
    if not ret_account then
		return error_code.ERROR_ADD_ITEM
	end

    return error_code.COMMON_SUCCESS, user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal]
end

--客户端领取累计收益广告奖励
local function get_accumulate_reward_advert(t_config)
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (get_accumulate_reward_advert) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil").." tag="..(tonumber(ngx.ctx.m_params.tag) or "nil"))

        return error_code.ERROR_PARAM
	end
    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 

    local ret, user_tag_data = gg.private_hash_get_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag])
    if ret~=error_code.COMMON_SUCCESS then 
        return error_code.ERROR_NO_DATA
    end

    --弱网环境已领奖校验
    if not user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert] 
    or user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert].reward_status ~= g_enum.Mode_accumulate.reward_status.ready then 
        return error_code.ALREADY_GET_REWARDS
    end

    --清掉找回奖励并回写ssdb
    user_tag_data.back_reward = nil 
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert] = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert] or {}
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert].reward_status = g_enum.Mode_accumulate.reward_status.finish
    --写入ssdb
    local ret = gg.private_hash_set_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, 
        g_enum.Mode_accumulate.accumulate_ssdb_keys[tag], user_tag_data)
    if ret~=true then 
        return error_code.ERROR_OP
    end

    --发广告奖励
    local rewards = {}
    for item_id, v in pairs(user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert]) do
        if type(v)=='table' then 
            table.insert(rewards, {id=item_id, num=v.total_num})
        end
    end
    local ret_account = ns_account.private_account.items_add(rewards, "accumulate_advert_rewards")
    if not ret_account then
		return error_code.ERROR_ADD_ITEM
	end

    return error_code.COMMON_SUCCESS, user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert]
end

--客户端领取累计收益广告奖励
local function get_accumulate_reward_all(t_config)
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (get_accumulate_reward_all) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil").." tag="..(tonumber(ngx.ctx.m_params.tag) or "nil"))

        return error_code.ERROR_PARAM
	end
    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 

    local ret, user_tag_data = gg.private_hash_get_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag])
    if ret~=error_code.COMMON_SUCCESS then 
        return error_code.ERROR_NO_DATA
    end

    --弱网环境已领奖校验
    if not user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal]
    or not user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert]
    or user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal].reward_status ~= g_enum.Mode_accumulate.reward_status.ready 
    or user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert].reward_status ~= g_enum.Mode_accumulate.reward_status.ready then 
        return error_code.ALREADY_GET_REWARDS
    end

    --弹窗初始时间修改
    local now_time = uu.now()
    user_tag_data.now_time = now_time
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert] = user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert] or {}
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.normal].reward_status = g_enum.Mode_accumulate.reward_status.finish
    
    --清掉找回奖励并回写ssdb
    user_tag_data.back_reward = nil 
    user_tag_data.rewards_table[g_enum.Mode_accumulate.accumulate_rewards.advert].reward_status = g_enum.Mode_accumulate.reward_status.finish
    
    --写入ssdb
    local ret = gg.private_hash_set_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, 
        g_enum.Mode_accumulate.accumulate_ssdb_keys[tag], user_tag_data)
    if ret~=true then 
        return error_code.ERROR_OP
    end

    --这里转换一下，客户端需要的结构
    local ret_data = {}
    for _, type_rewards_t in pairs(user_tag_data.rewards_table) do
        for item_id, item_data in pairs(type_rewards_t) do
            if type(item_data)=='table' then 
                ret_data[item_id] = ret_data[item_id] or {}
                ret_data[item_id].total_num = ret_data[item_id].total_num or 0
                ret_data[item_id].total_num = ret_data[item_id].total_num + item_data.total_num
            end 
        end
    end

    --发奖
    local rewards = {}
    for item_id, data in pairs(ret_data) do
        table.insert(rewards, {id=item_id, num=data.total_num})
    end
    local ret_account = ns_account.private_account.items_add(rewards, "accumulate_all_rewards")
    if not ret_account then
        return error_code.ERROR_ADD_ITEM
    end

    return error_code.COMMON_SUCCESS, ret_data
end

--领奖
FOO.get_accumulate_reward = function()
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) 
    or not tonumber(ngx.ctx.m_params.reward_type) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (accumulate_get_reward) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil").."  tag="..(tonumber(ngx.ctx.m_params.tag) or "nil")
            .." reward_type= "..(tonumber(ngx.ctx.m_params.reward_type) or "nil") )
        return error_code.ERROR_PARAM
    end

    --配置检查
    local t_config = config.get_cfg("Mode_accumulate")
    if not t_config 
    or not t_config.back_reward_time then  
        return error_code.ERROR_CHECK_CONFIG
    end 
    --不符合活动时间则return
    local now_time = uu.now()
    if (now_time<t_config.starttime) or (now_time>t_config.endtime+60) then 
        return error_code.ERROR_LIMIT_TIME
    end

    local code, ret_table
    --普通奖励
    if tonumber(ngx.ctx.m_params.reward_type)==g_enum.Mode_accumulate.accumulate_get_type.normal then 
        code, ret_table = get_accumulate_reward_normal(t_config)
    --广告奖励
    elseif tonumber(ngx.ctx.m_params.reward_type)==g_enum.Mode_accumulate.accumulate_get_type.advert then 
        code, ret_table = get_accumulate_reward_advert()
    --普通+广告
    elseif tonumber(ngx.ctx.m_params.reward_type)==g_enum.Mode_accumulate.accumulate_get_type.all then 
        code, ret_table = get_accumulate_reward_all()
    end

    log.day_list("get_accumulate_reward", "[INFO] get_accumulate_reward uin="..tonumber(ngx.ctx.m_params.uin) .." reward_type="..tonumber(ngx.ctx.m_params.reward_type)
        .." tag="..tonumber(ngx.ctx.m_params.tag).." ret="..table.tostring(ret_table or {}))

    return code, ret_table
end

--写入增益活动
FOO.set_accumulate_delta_task = function ()
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) 
    or not tonumber(ngx.ctx.m_params.task_id) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (set_accumulate_delta_task) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil").."  tag="..(tonumber(ngx.ctx.m_params.tag) or "nil")
            .." task_id= "..(tonumber(ngx.ctx.m_params.task_id) or "nil") )

        return error_code.ERROR_PARAM
	end

    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 
    local task_id = tonumber(ngx.ctx.m_params.task_id) 

    --配置检查
    local t_config = config.get_cfg("Mode_accumulate")
    if not t_config
    or not t_config.delta_list 
    or not t_config.delta_list[task_id] then
        return error_code.ERROR_CHECK_CONFIG
    end

    local ret, user_tag_data = gg.private_hash_get_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag])
    --将活动配置数据加进来
    local task_detail = {}
    task_detail.task_name = t_config.delta_list[task_id].task_name or "default_task_name"
    task_detail.delta_id = t_config.delta_list[task_id].delta_id or 0
    task_detail.delta_rate = t_config.delta_list[task_id].delta_rate or 0
    task_detail.vaild_time = t_config.delta_list[task_id].vaild_time or 0
    task_detail.items = t_config.delta_list[task_id].items or {}
    task_detail.delta_limit = t_config.delta_list[task_id].delta_limit or 0
    task_detail.start_ts = uu.now()
    task_detail.total_delta_time = 0

    if not user_tag_data.delta_list then 
        user_tag_data.delta_list = {}
    end
    table.insert(user_tag_data.delta_list, task_detail)
    --写入ssdb
    local ret = gg.private_hash_set_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, 
        g_enum.Mode_accumulate.accumulate_ssdb_keys[tag], user_tag_data)
    if ret~=true then 
        return error_code.ERROR_OP
    end

    log.day_list("set_accumulate_delta_task", "[INFO] set_accumulate_delta_task uin="..uin.." tag="..tonumber(ngx.ctx.m_params.tag)
        .." task_id="..tonumber(ngx.ctx.m_params.task_id).." ret="..table.tostring(task_detail))

    return error_code.COMMON_SUCCESS, task_detail
end

--查玩家累计数据
FOO.get_user_accumulate_data = function ()
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (get_user_accumulate_data) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil").." tag= "..(tonumber(ngx.ctx.m_params.tag) or "nil") )

        return error_code.ERROR_PARAM
	end

    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 

    local ret, user_tag_data = gg.private_hash_get_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag])
    if ret~=error_code.COMMON_SUCCESS then 
        return error_code.ERROR_NO_DATA
    end

    return error_code.COMMON_SUCCESS, user_tag_data
end

--清除玩家累计数据
FOO.clear_user_accumulate_data = function ()
    if not tonumber(ngx.ctx.m_params.uin) 
    or not tonumber(ngx.ctx.m_params.tag) then
        log.day_list(g_enum.Mode_accumulate.welfare_advert, "[ERROR] (clear_user_accumulate_data) ERROR_PARAM!  uin= "
            ..(tonumber(ngx.ctx.m_params.uin) or "nil").." tag="..(tonumber(ngx.ctx.m_params.tag) or "nil") )

        return error_code.ERROR_PARAM
	end

    local uin = tonumber(ngx.ctx.m_params.uin)
    local tag = tonumber(ngx.ctx.m_params.tag) 

    local ret = gg.private_hash_set_table_ssdb(ngx.ctx.m_params.uin, ngx.ctx.m_params.uin, g_enum.Mode_accumulate.accumulate_ssdb_keys[tag], {},  g_enum.Mode_accumulate._WRITE_SSDB_WITHOUT_LOCK_)
    if ret~=true then 
        return error_code.ERROR_OP
    end

    return error_code.COMMON_SUCCESS
end


return FOO